package lib.bone.flow.module.processor.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.lang.Validator;
import cn.hutool.json.JSONUtil;
import lib.bone.common.utils.JsonUtil;
import lib.bone.flow.constant.FlowNodeTypeConst;
import lib.bone.flow.constant.FlowTaskStatusConst;
import lib.bone.flow.domain.dto.FlowParam;
import lib.bone.flow.domain.entity.FlowTask;
import lib.bone.flow.domain.entity.FlowWork;
import lib.bone.flow.domain.model.BaseModel;
import lib.bone.flow.domain.model.FlowModel;
import lib.bone.flow.domain.model.TaskModel;
import lib.bone.flow.event.FlowTaskCreatedEvent;
import lib.bone.flow.event.FlowTaskNodeEvent;
import lib.bone.flow.module.loader.FlowNodeUserLoader;
import lib.bone.flow.module.processor.FlowNodeProcessor;
import lib.bone.flow.service.FlowTaskService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @author: kindear
 */
@Slf4j
@Service
public class TaskNodeProcessorImpl implements FlowNodeProcessor {

    @Autowired(required = false)
    FlowNodeUserLoader flowNodeUserLoader;

    @Autowired(required = false)
    FlowTaskCreatedEvent flowTaskCreatedEvent;

    @Autowired(required = false)
    FlowTaskNodeEvent flowTaskNodeEvent;

    @Autowired
    FlowTaskService flowTaskService;

    @Override
    public String getNodeType() {
        // 任务节点
        return FlowNodeTypeConst.TASK_NODE;
    }

    @Override
    public void process(FlowWork flowWork, FlowModel flowModel, BaseModel currentNddeModel, FlowParam flowParam) {
        TaskModel taskModel = (TaskModel) currentNddeModel;
        // 创建任务
        createTask(flowWork,flowParam,taskModel);
        // 触发事件
        if (Validator.isNotEmpty(flowTaskNodeEvent)){
            flowTaskNodeEvent.onEvent(flowWork,taskModel,flowParam);
        }
    }

    @Override
    public void back(FlowWork flowWork, FlowModel flowModel, BaseModel currentNddeModel, FlowParam flowParam) {

    }

    /**
     * 创建任务Task
     * @param flowWork
     * @param flowParam
     * @param taskModel
     * @return
     */
    @Transactional
    public int createTask(FlowWork flowWork, FlowParam flowParam, TaskModel taskModel){
        log.info("TASK 创建任务");
        Map<String,String> ext = taskModel.getExt();
        String usersJsonStr = ext.get("userIds");
        List<String> userIds = new ArrayList<>();
        if(Validator.isNotEmpty(usersJsonStr)){
            userIds = JSONUtil.toList(usersJsonStr,String.class);
        }
        Set<String> taskUsers = new HashSet<>(userIds);
        /**
         * 获取流程实例ID
         */
        String flowWorkId = flowWork.getId();
        if (Validator.isNotEmpty(flowNodeUserLoader)){
            List<String> loadUsers = flowNodeUserLoader.loadUsers(flowWork,taskModel,flowParam);
            taskUsers.addAll(loadUsers);
        }
        //List<FlowTask> flowTasks = new ArrayList<>();
        /**
         * 构建TASK 并写入操作人员信息
         */
        FlowTask task = new FlowTask();
        //流转方式

        // 发起人信息
        task.setInitiator(flowWork.getInitiator());
        // 获取操作人员信息 可以通过接口实现 由 interface 获取
        task.setOperator(flowParam.getOperator());
        task.setServiceType(flowParam.getServiceType());
        task.setServiceId(flowParam.getServiceId());
        // fix 新增 serviceName
        task.setServiceName(flowParam.getServiceName());
        task.setTaskName(taskModel.getName());
        task.setFlowNodeId(taskModel.getId());
        task.setTaskStatus(FlowTaskStatusConst.CREATED);
        task.setFlowParam(JsonUtil.obj2String(flowParam));
        task.setFlowWorkId(flowWorkId);
        // 设置流程任务状态
        task.setStatus(1);
        for (String userId:taskUsers){
            FlowTask insertVal = new FlowTask();
            BeanUtil.copyProperties(task,insertVal, CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
           // log.info("写入"+userId);
            insertVal.setActUserId(userId);
            //flowTasks.add(task);
            FlowTask execRes = flowTaskService.saveOne(insertVal);
            if(Validator.isNotEmpty(flowTaskCreatedEvent)){
                // 触发创建事件
                flowTaskCreatedEvent.onEvent(flowWork,execRes,flowParam);
            }
        }

        return taskUsers.size();
    }
}
